home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / Mesa-3.0 / SAMPLES / NURB.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-07-26  |  6.3 KB  |  350 lines

  1. /*
  2.  * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that (i) the above copyright notices and this permission notice appear in
  7.  * all copies of the software and related documentation, and (ii) the name of
  8.  * Silicon Graphics may not be used in any advertising or
  9.  * publicity relating to the software without the specific, prior written
  10.  * permission of Silicon Graphics.
  11.  *
  12.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
  13.  * ANY KIND,
  14.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  15.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  16.  *
  17.  * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
  18.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  19.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  20.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
  21.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  22.  * OF THIS SOFTWARE.
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <math.h>
  29. #include <GL/glut.h>
  30.  
  31.  
  32. #define INREAL float
  33.  
  34. #define S_NUMPOINTS 13
  35. #define S_ORDER     3   
  36. #define S_NUMKNOTS  (S_NUMPOINTS + S_ORDER)
  37. #define T_NUMPOINTS 3
  38. #define T_ORDER     3 
  39. #define T_NUMKNOTS  (T_NUMPOINTS + T_ORDER)
  40. #define SQRT_TWO    1.41421356237309504880
  41.  
  42.  
  43. typedef INREAL Point[4];
  44.  
  45.  
  46. GLenum doubleBuffer;
  47.  
  48. GLenum expectedError;
  49. GLint rotX = 40, rotY = 40;
  50. INREAL sknots[S_NUMKNOTS] = {
  51.     -1.0, -1.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0,
  52.     4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 9.0, 9.0
  53. };
  54. INREAL tknots[T_NUMKNOTS] = {
  55.     1.0, 1.0, 1.0, 2.0, 2.0, 2.0
  56. };
  57. Point ctlpoints[S_NUMPOINTS][T_NUMPOINTS] = {
  58.     {
  59.     {
  60.         4.0, 2.0, 2.0, 1.0
  61.     },
  62.     {
  63.         4.0, 1.6, 2.5, 1.0
  64.     },
  65.     {
  66.         4.0, 2.0, 3.0, 1.0
  67.     }
  68.     },
  69.     {
  70.     {
  71.         5.0, 4.0, 2.0, 1.0
  72.     },
  73.     {
  74.         5.0, 4.0, 2.5, 1.0
  75.     },
  76.     {
  77.         5.0, 4.0, 3.0, 1.0
  78.     }
  79.     },
  80.     {
  81.     {
  82.         6.0, 5.0, 2.0, 1.0
  83.     },
  84.     {
  85.         6.0, 5.0, 2.5, 1.0
  86.     },
  87.     {
  88.         6.0, 5.0, 3.0, 1.0
  89.     }
  90.     },
  91.     {
  92.     {
  93.         SQRT_TWO*6.0, SQRT_TWO*6.0, SQRT_TWO*2.0, SQRT_TWO
  94.     },
  95.     {
  96.         SQRT_TWO*6.0, SQRT_TWO*6.0, SQRT_TWO*2.5, SQRT_TWO
  97.     },
  98.     {
  99.         SQRT_TWO*6.0, SQRT_TWO*6.0, SQRT_TWO*3.0, SQRT_TWO
  100.     }  
  101.     },
  102.     {
  103.     {
  104.         5.2, 6.7, 2.0, 1.0
  105.     },
  106.     {
  107.         5.2, 6.7, 2.5, 1.0
  108.     },
  109.     {
  110.         5.2, 6.7, 3.0, 1.0
  111.     }
  112.     },
  113.     {
  114.     {
  115.         SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*2.0, SQRT_TWO
  116.     },
  117.     {
  118.         SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*2.5, SQRT_TWO
  119.     }, 
  120.     {
  121.         SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*3.0, SQRT_TWO
  122.     }  
  123.     }, 
  124.     {
  125.     {
  126.         4.0, 5.2, 2.0, 1.0
  127.     },
  128.     {
  129.         4.0, 4.6, 2.5, 1.0
  130.     },
  131.     {
  132.         4.0, 5.2, 3.0, 1.0
  133.     }  
  134.     },
  135.     {
  136.     {
  137.         SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*2.0, SQRT_TWO
  138.     },
  139.     {
  140.         SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*2.5, SQRT_TWO
  141.     },
  142.     {
  143.         SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*3.0, SQRT_TWO
  144.     }  
  145.     },
  146.     {
  147.     {
  148.         2.8, 6.7, 2.0, 1.0
  149.     },
  150.     {
  151.         2.8, 6.7, 2.5, 1.0
  152.     },
  153.     {
  154.         2.8, 6.7, 3.0, 1.0
  155.     }   
  156.     },
  157.     {
  158.     {
  159.         SQRT_TWO*2.0, SQRT_TWO*6.0, SQRT_TWO*2.0, SQRT_TWO
  160.     },
  161.     {
  162.         SQRT_TWO*2.0, SQRT_TWO*6.0, SQRT_TWO*2.5, SQRT_TWO
  163.     },
  164.     {
  165.         SQRT_TWO*2.0, SQRT_TWO*6.0, SQRT_TWO*3.0, SQRT_TWO
  166.     }  
  167.     },
  168.     {
  169.     {
  170.         2.0, 5.0, 2.0, 1.0
  171.     },
  172.     {
  173.         2.0, 5.0, 2.5, 1.0
  174.     },
  175.     {
  176.         2.0, 5.0, 3.0, 1.0
  177.     } 
  178.     },
  179.     {
  180.     {
  181.         3.0, 4.0, 2.0, 1.0
  182.     },
  183.     {
  184.         3.0, 4.0, 2.5, 1.0
  185.     },
  186.     {
  187.         3.0, 4.0, 3.0, 1.0
  188.     } 
  189.     },
  190.     {
  191.     {
  192.         4.0, 2.0, 2.0, 1.0
  193.     },
  194.     {
  195.         4.0, 1.6, 2.5, 1.0
  196.     },
  197.     {
  198.         4.0, 2.0, 3.0, 1.0
  199.     }    
  200.     }
  201. };
  202. GLUnurbsObj *theNurbs;
  203.  
  204.  
  205. static void CALLBACK ErrorCallback(GLenum which)
  206. {
  207.  
  208.     if (which != expectedError) {
  209.     fprintf(stderr, "Unexpected error occured (%d):\n", which);
  210.     fprintf(stderr, "    %s\n", (char *) gluErrorString(which));
  211.     }
  212. }
  213.  
  214. static void Init(void)
  215. {
  216.  
  217.     theNurbs = gluNewNurbsRenderer();
  218.     gluNurbsCallback(theNurbs, GLU_ERROR, ErrorCallback);
  219.  
  220.     gluNurbsProperty(theNurbs, GLU_SAMPLING_TOLERANCE, 15.0);
  221.     gluNurbsProperty(theNurbs, GLU_DISPLAY_MODE, GLU_OUTLINE_PATCH);
  222.  
  223.     expectedError = GLU_INVALID_ENUM;
  224.     gluNurbsProperty(theNurbs, ~0, 15.0);
  225.     expectedError = GLU_NURBS_ERROR13;
  226.     gluEndSurface(theNurbs);
  227.     expectedError = 0;
  228.  
  229.     glColor3f(1.0, 1.0, 1.0);
  230. }
  231.  
  232. static void Reshape(int width, int height)
  233. {
  234.  
  235.     glViewport(0, 0, (GLint)width, (GLint)height);
  236.  
  237.     glMatrixMode(GL_PROJECTION);
  238.     glLoadIdentity();
  239.     glFrustum(-2.0, 2.0, -2.0, 2.0, 0.8, 10.0);
  240.     gluLookAt(7.0, 4.5, 4.0, 4.5, 4.5, 2.5, 6.0, -3.0, 2.0);
  241.     glMatrixMode(GL_MODELVIEW);
  242. }
  243.  
  244. static void Key2(int key, int x, int y)
  245. {
  246.  
  247.     switch (key) {
  248.       case GLUT_KEY_DOWN:
  249.     rotX -= 5;
  250.     break;
  251.       case GLUT_KEY_UP:
  252.     rotX += 5;
  253.     break;
  254.       case GLUT_KEY_LEFT:
  255.     rotY -= 5;
  256.     break;
  257.       case GLUT_KEY_RIGHT:
  258.     rotY += 5;
  259.     break;
  260.       default:
  261.     return;
  262.     }
  263.  
  264.     glutPostRedisplay();
  265. }
  266.  
  267. static void Key(unsigned char key, int x, int y)
  268. {
  269.  
  270.     switch (key) {
  271.       case 27:
  272.     exit(1);
  273.     }
  274. }
  275.  
  276. static void Draw(void)
  277. {
  278.  
  279.     glClear(GL_COLOR_BUFFER_BIT);
  280.  
  281.     glPushMatrix();
  282.  
  283.     glTranslatef(4.0, 4.5, 2.5);
  284.     glRotatef(rotY, 1, 0, 0);
  285.     glRotatef(rotX, 0, 1, 0);
  286.     glTranslatef(-4.0, -4.5, -2.5);
  287.  
  288.     gluBeginSurface(theNurbs);
  289.     gluNurbsSurface(theNurbs, S_NUMKNOTS, sknots, T_NUMKNOTS, tknots,
  290.             4*T_NUMPOINTS, 4, &ctlpoints[0][0][0], S_ORDER,
  291.             T_ORDER, GL_MAP2_VERTEX_4);
  292.     gluEndSurface(theNurbs);
  293.  
  294.     glPopMatrix();
  295.  
  296.     glFlush();
  297.  
  298.     if (doubleBuffer) {
  299.     glutSwapBuffers();
  300.     }
  301. }
  302.  
  303. static GLenum Args(int argc, char **argv)
  304. {
  305.     GLint i;
  306.  
  307.     doubleBuffer = GL_FALSE;
  308.  
  309.     for (i = 1; i < argc; i++) {
  310.     if (strcmp(argv[i], "-sb") == 0) {
  311.         doubleBuffer = GL_FALSE;
  312.     } else if (strcmp(argv[i], "-db") == 0) {
  313.         doubleBuffer = GL_TRUE;
  314.     } else {
  315.         printf("%s (Bad option).\n", argv[i]);
  316.         return GL_FALSE;
  317.     }
  318.     }
  319.     return GL_TRUE;
  320. }
  321.  
  322. void main(int argc, char **argv)
  323. {
  324.     GLenum type;
  325.  
  326.     glutInit(&argc, argv);
  327.  
  328.     if (Args(argc, argv) == GL_FALSE) {
  329.     exit(1);
  330.     }
  331.  
  332.     glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
  333.  
  334.     type = GLUT_RGB;
  335.     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
  336.     glutInitDisplayMode(type);
  337.  
  338.     if (glutCreateWindow("NURBS Test") == GL_FALSE) {
  339.     exit(1);
  340.     }
  341.  
  342.     Init();
  343.  
  344.     glutReshapeFunc(Reshape);
  345.     glutKeyboardFunc(Key);
  346.     glutSpecialFunc(Key2);
  347.     glutDisplayFunc(Draw);
  348.     glutMainLoop();
  349. }
  350.